<!doctype html>
<html lang="en">
	<head>
		<meta charset="UTF-8">
		<title>svg</title>
		<script src="d3.js"></script>
		<style>
			#chart{
				width: 800px;
				height: 500px;
				margin: 0 auto;
				border: 1px solid blue;
				background-color: #f5f6f7;
			}
			.h-bar {
				margin-bottom: 2px;
				border: 1px solid blue;
				background-color: #ccc;
			}
			.v-bar,.cell {
				margin-bottom: 2px;
				margin-right: 2px;
				padding: 10px;
				border: 1px solid blue;
				background-color: #ccc;
			}
			.fixed-cell{
				position:  absolute;
				margin-bottom: 2px;
				margin-right: 2px;
				padding: 10px;
				border: 1px solid blue;
				background-color: #ccc;
			}
		</style>
	</head>
	<body>
		<div id="chart"></div>
		<script> 

			var functionality = [
				{a: 'Axial', b: 'Full 2.0s'},
				{a: '40mm', b: '0.625*12', c: 'Large'},
				{a: '120kv', b: 'Smart mA', c: '10-200v'},
				{a: '4.1s', b: '3.2s', c: '--.--s'}
			];

			var radius = 30, width = 800, height = 500;
			var offset = {x: 0, y: 0};
			var start = {cx: 0, cy : 0};
			var end = {cx: 0, cy: 0};
  
			var drag =
				d3.behavior.drag()
					.on('dragstart', dragstart)
					.on('drag', drag)
					.on('dragend', dragend)
 
			var svg = d3.select('#chart')
						.append('svg')
						.attr({
							height: '100%',
							width : '100%'
						});
			
			var functionalNodes = svg.append('g');
			
			functionalNodes
				.selectAll('circle')
				.data(functionality)
				.enter()
				.append('circle')
				.attr({
					cx: function(d, i) {
						return (Math.floor(i / 2) + 1) * (radius * 2 + 80) + 'px';
					},
					cy: function(d, i) {
						return (i % 2 + 1) * (radius * 2 + 80) + 'px';
					},
					r: radius,
					fill: '#999'
				})
				.call(drag)	 
				
			//functionalNodes
			//	.selectAll('text')
			//	.data(functionality)
			//	.enter()			
			//	.append('text')
			//	.text(function(d) {
			//		return d.a + "\n" + d.b + "<br>" + d.c;
			//	})
			//	.attr({
			//		x: radius * 2 + 50 + 'px'
			//	})
			//	.each(function(d, i) {
			//		d3.select(this)
			//			.attr('y', function(d) {
			//				return (i + 1) * (radius * 2 + 20) + 'px';
			//			});
			//	});
 
				function dragstart() { 
					var this_ = d3.select(this).classed('active', true);
					var mouseThis_ = d3.mouse(this);
					start.cx = parseFloat(this_.attr('cx'));
					start.cy = parseFloat(this_.attr('cy'));
 
					offset.x = start.cx - mouseThis_[0];
					offset.y = start.cy - mouseThis_[1];
				}

				var highlight = function(shape) {
					shape
						.transition()
						.duration(100)
						.attr('fill', 'orange');
				}
				var removeHighlighting = function(shape) {
					shape
						.transition()
						.duration(100)
						.attr('fill', '#999999');
				}
				
		 		function drag(d) {
			 		// move
			 		var cur = d3.mouse(this);
					d3.select(this)
						.attr({
							cx: Math.max(radius, Math.min(width - radius, cur[0] + offset.x)),
							cy: Math.max(radius, Math.min(height - radius, cur[1] + offset.y))
						});

 					// highlight when touched
					var otherNodes = d3.select('#chart')
									 	.selectAll('circle:not(.active)');
									 	
					otherNodes.each(function(d, i) {
						var this_ = d3.select(this),
							cx = parseFloat(this_.attr('cx')),
							cy = parseFloat(this_.attr('cy'));
						
						if ((Math.pow(cx - cur[0] - offset.x, 2) 
								+ Math.pow(cy - cur[1] - offset.y, 2))
								< 4 * Math.pow(radius, 2)) {
							highlight(this_);
							end.cx = cx;
							end.cy = cy;
							//console.log(end.cx + ' ' + end.cy);
						} else {
							removeHighlighting(this_);
							end.cx = 0;
							end.cy = 0;
							//console.log(end.cx + ' ' + end.cy);
						}
					});
		 		}				
				
				function dragend(d) {
					var this_ = d3.select(this).classed('active', false);
					functionalNodes.each(function(d, i) {
						console.log(i);
						removeHighlighting(d3.select(this));
					});
					
					this_
						.transition()
						.duration(500)
						.attr({
							cx: start.cx,
							cy: start.cy
						});
					var cur = {
						cx: parseFloat(this_.attr('cx')),
						cy: parseFloat(this_.attr('cy'))
					};
					
					if (end.cx + end.cy !== 0) {						
						drawLine(functionalNodes, start, end);
					}
		 		}

		 		function drawLine(parent, e1, e2) {
			 		parent.append('line')
			 			.attr({
				 			x1: e1.cx,
				 			y1: e1.cy,
				 			x2: e2.cx,
				 			y2: e2.cy,
				 			stroke: '#999999',
				 			'stroke-width': 1
			 			});
		 		}
		</script>
	</body>

</html>